package com.mz.system.provider.controller;

import cn.hutool.core.lang.tree.Tree;
import com.mz.common.core.entity.R;
import com.mz.common.log.annotation.MzLog;
import com.mz.common.log.enums.BusinessType;
import com.mz.common.validated.groups.UpdateField;
import com.mz.system.model.dto.SysMenuDto;
import com.mz.system.model.entity.SysMenuEntity;
import com.mz.system.model.vo.MenuMenuVo;
import com.mz.system.model.vo.SysMenuTree;
import com.mz.system.model.vo.req.SysMenuReqVo;
import com.mz.system.model.vo.res.MenuResVo;
import com.mz.system.provider.service.SysMenuService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Size;
import java.util.Arrays;
import java.util.List;


/**
 * 菜单权限表
 *
 * @author 小政同学 QQ:xiaozheng666888@qq.com
 * @email 1911298402@qq.com
 * @date 2021-11-13 22:14:36
 */
@Api(tags = "菜单权限表")
@RestController
@RequestMapping("admin/sysmenu")
@RequiredArgsConstructor
public class SysMenuController {
    private final SysMenuService sysMenuService;


    /**
     * 获取用户菜单树
     * @return 用户所具有的菜单树
     */
    @ApiOperation(value = "获取用户菜单树", notes = "根据用户查询用户具有的菜单")
    @GetMapping("/getUserMenuTree")
    public R<List<MenuResVo>> getUserMenuTree() {
        List<SysMenuDto> menuTree = sysMenuService.getUserMenuTree();
        return R.ok(sysMenuService.buildMenus(menuTree));
    }

    /**
     * 获取菜单树
     * @return 下拉列表树
     */
    @ApiOperation(value = "获取菜单树", notes = "下拉框中选择")
    @GetMapping("/getMenuTree")
    public R<List<Tree<Long>>> getMenuTree() {
        List<Tree<Long>> menuTree = sysMenuService.getMenuTree();
        return R.ok(menuTree);
    }


    /**
     * 获取菜单列表树
     * @param sysMenuVo 实体对象
     * @return 菜单树列表
     */
    @ApiOperation(value = "获取菜单列表树", notes = "菜单列表")
    @PreAuthorize("@pms.hasPermission('system:menu:query')")
    @GetMapping("/getMenuListTree")
    public R<List<SysMenuTree>> getMenuListTree(SysMenuReqVo sysMenuVo) {
        List<SysMenuTree> menuTree = sysMenuService.getMenuListTree(sysMenuVo);
        return R.ok(menuTree);
    }


    /**
     * 通过菜单ID查询单条数据
     *
     * @param menuId 菜单ID
     * @return 单条数据
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "menuId", value = "主键", dataTypeClass = Long.class, paramType = "path", example = "1")
    })
    @ApiOperation("通过菜单ID查询单条数据")
    @PreAuthorize("@pms.hasPermission('system:menu:query')")
    @GetMapping("/info/{menuId}")
    public R<SysMenuEntity> info(@PathVariable("menuId") Long menuId) {
        SysMenuEntity sysMenu = sysMenuService.getById(menuId);
        return R.ok(sysMenu);
    }

    /**
     * 保存菜单
     *
     * @param sysMenuVo 实体对象
     * @return 新增结果
     */
    @ApiOperation("保存菜单")
    @MzLog(title = "菜单管理",businessType = BusinessType.SAVE)
    @PreAuthorize("@pms.hasPermission('system:menu:save')")
    @PostMapping("/save")
    public R<Boolean> save(@Validated @RequestBody MenuMenuVo sysMenuVo) {
        boolean save = sysMenuService.saveMenu(sysMenuVo);
        return R.okOrFail(save, "保存");
    }

    /**
     * 修改菜单
     *
     * @param sysMenuVo 实体对象
     * @return 修改结果
     */
    @ApiOperation("修改菜单")
    @MzLog(title = "菜单管理",businessType = BusinessType.UPDATE)
    @PreAuthorize("@pms.hasPermission('system:menu:update')")
    @PutMapping("/update")
    public R<Boolean> update(@Validated(UpdateField.class) @RequestBody MenuMenuVo sysMenuVo) {
        boolean update = sysMenuService.updateMenuById(sysMenuVo);
        return R.okOrFail(update, "更新");
    }

    /**
     * 删除菜单
     *
     * @param menuIds 菜单ID集合/数组
     * @return 删除结果
     */
    @ApiOperation("删除数据")
    @MzLog(title = "菜单管理",businessType = BusinessType.REMOVE)
    @PreAuthorize("@pms.hasPermission('system:menu:delete')")
    @DeleteMapping("/delete")
    public R<Boolean> delete(@RequestBody @Validated @Size(min = 1) Long[] menuIds) {
        boolean remove = sysMenuService.removeByIds(Arrays.asList(menuIds));
        return R.okOrFail(remove, "删除");
    }

}
